from fastapi import Request, File, UploadFile, Form
from tortoise.transactions import in_transaction
import os

from service import UserService, SongService
from common.result.Result import Result
from common.enum import BaseEnum
from util.log import Log
from util.str import Str
from util.crypto import Crypto
from models.song import Song

async def UploadSong(req: Request, 
                     token: str = Form(), 
                     name: str = Form(),
                     singer: str = Form(),
                     duration: int = Form(),
                     uploadField: UploadFile = File(...)
                     ):
    try:
        async with in_transaction() as connection:
            if Str.isBlank(token):
                return Result.error(BaseEnum.PARAMETER_INVALID_ERROR)

            user = await UserService.getUserByToken(token)
            if user == None:
                return Result.error(BaseEnum.USER_NOT_EXISTS_ERROR)
            
            if user.username != 'helloyt':
                return Result.error(BaseEnum.ADMIN_PERMISSION_ERROR)

            songData = await uploadField.read()
            md5 = Crypto.fileMD5(songData)
            song = await SongService.getSongByMD5(md5)
            if song != None:
                return Result.error(BaseEnum.SONG_ALREADY_EXIST_ERROR)

            path = os.path.join(os.path.realpath(os.curdir), "upload_file")
            if (os.path.exists(path) == False):
                os.makedirs(path)

            # 相当于 /home/helloyt/backend/upload-file/filename
            filepath = os.path.join(path, uploadField.filename)
            
            f = open(filepath, 'wb')
            f.write(songData)
            f.close()

            # rfind 找不到返回 -1; 不要用 rindex，会抛异常;
            ext = uploadField.filename[uploadField.filename.rfind('.') : ]

            res = await SongService.createSong({
                "name": name,
                "singer": singer,
                "duration": duration,
                "md5": md5,
                "ext": ext
            })

            return Result.success(res)
    except Exception as e:
        Log.error('上传 song 异常', e)
        return Result.error(BaseEnum.SERVICE_ERROR)


